import os
from pathlib import Path
from typing import List

from pydantic import Field
from pydantic_settings import BaseSettings, SettingsConfigDict

# 获取项目根目录（common的父目录）
PROJECT_ROOT = Path(__file__).parent.parent


# 根据环境变量动态确定要加载的配置文件
def get_env_files():
	"""根据ENV环境变量动态确定要加载哪些配置文件"""
	env = os.getenv("ENV", "test")
	# 基础配置 + 环境特定配置
	if env == "dev":
		return (str(PROJECT_ROOT / ".env"),)  # 只加载 .env
	elif env == "test":
		return (str(PROJECT_ROOT / ".env"), str(PROJECT_ROOT / ".env.test"))  # 先加载 .env，再用 .env.test 覆盖
	elif env == "show":
		return (str(PROJECT_ROOT / ".env"), str(PROJECT_ROOT / ".env.show"))  # 先加载 .env，再用 .env.show 覆盖
	elif env == "prod":
		return (str(PROJECT_ROOT / ".env"), str(PROJECT_ROOT / ".env.prod"))  # 先加载 .env，再用 .env.prod 覆盖
	else:
		return (str(PROJECT_ROOT / ".env"),)  # 默认只加载 .env


class Settings(BaseSettings):
	# 运行环境
	env: str = "dev"

	# 数据库
	db_host: str = "localhost"
	db_port: int = 3306
	db_user: str = "root"
	db_password: str = "root"
	db_name: str = "materops"

	# 数据库连接池配置
	db_pool_size: int = Field(default=30, description="数据库连接池大小，默认30个连接（增加以防止连接池满）")

	# MQTT
	mqtt_broker: str = "localhost"
	mqtt_port: int = 1883
	# MQTT订阅主题(根据环境不同订阅不同的topic)
	mqtt_subscribe_topic: str = "/meter/+/telemetry"
	mqtt_topics: List[str] = Field(
		default_factory=lambda: [v.strip() for v in
								 os.getenv("MQTT_TOPICS", "v1/test_consumer").split(",")]
	)
	mqtt_user: str = "admin"
	mqtt_password: str = "StrongPass!123"
	mqtt_ca_cert: str | None = None
	# 发送端配置
	mqtt_command_topic_prefix: str = "device/command"  # 命令主题前缀
	mqtt_response_topic_prefix: str = "device/response"  # 响应主题前缀
	command_timeout: int = 30  # 命令超时时间（秒）
	max_command_retries: int = 3  # 最大命令重试次数

	# API
	api_host: str = "0.0.0.0"
	api_port: int = 8000
	max_reconnect_attempts: int = 5
	reconnect_delay: int = 5

	# JWT
	jwt_secret_key: str = "secret-key"
	jwt_algorithm: str = "HS256"
	access_token_expire_minutes: int = 720
	cors_origins: str = ""

	# 日志
	log_level: str = "INFO"
	log_file: str | None = Field(default=None, description="日志文件路径，不指定则自动生成到logs目录")
	enable_file_logging: bool = Field(default=True, description="是否启用文件日志")

	# Redis
	redis_host: str = "localhost"
	redis_port: int = 6379
	redis_password: str | None = None
	redis_db: int = 0
	redis_max_connections: int = 20
	redis_socket_timeout: int = 5
	redis_socket_connect_timeout: int = 5
	redis_health_check_interval: int = 30

	# OSS
	OSS_ACCESS_KEY_ID: str = ""
	OSS_ACCESS_KEY_SECRET: str = ""
	OSS_ENDPOINT: str = ""
	OSS_BUCKET: str = ""

	# 文件上传配置
	max_file_size: int = Field(default=50 * 1024 * 1024, description="最大文件大小（字节），默认50MB")
	upload_dir: str = Field(default="uploads", description="文件上传目录")
	allowed_file_types: List[str] = Field(
		default_factory=lambda: [
			# 图片
			"image/jpeg", "image/png", "image/gif", "image/webp", "image/bmp",
			# 文档
			"application/pdf",
			"application/vnd.openxmlformats-officedocument.wordprocessingml.document",  # .docx
			"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",  # .xlsx
			"application/vnd.ms-excel",  # .xls
			"application/msword",  # .doc
			"text/csv", "text/plain",
			# 压缩包
			"application/zip", "application/x-rar-compressed",
			# 其他
			"application/octet-stream",
		],
		description="允许上传的文件类型"
	)

	# Pydantic 元配置
	model_config = SettingsConfigDict(
		env_file=get_env_files(),  # 动态根据ENV加载配置文件
		env_file_encoding="utf-8",
		case_sensitive=False,
		extra="ignore",
	)

	@property
	def db_url(self) -> str:
		return (
			f"mysql+pymysql://{self.db_user}:{self.db_password}"
			f"@{self.db_host}:{self.db_port}/{self.db_name}"
		)


# 全局单例
settings = Settings()
